#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
const int SIZE =240;

bool mymap[SIZE][SIZE];
int areb[SIZE];//cow 2 stall
int brea[SIZE];//stall 2 cow
bool used[SIZE];//stall
int n,m;
int cnt=0;
void init();
void showmap();
void prework();
void showre();
void edmonds();
bool dfs(int );
int main()
{
    freopen("dat.in","r",stdin);
    freopen("dat.out","w",stdout);
    while (scanf("%d%d",&n,&m)!=EOF){
        init();
        prework();
        edmonds();
        showre();
    }
    return 0;
}
void edmonds(){
    int i;
    for (i=1;i<=n;i++){
        if (areb[i]==-1){
            memset(used,false,sizeof(used));
            if (dfs(i)){
                cnt++;
            }
        }
    }
}
bool dfs(int node){
    int i;
    for (i=1;i<=m;i++){
        if (!used[i] && mymap[node][i]){
            used[i]=true;
            if (brea[i]==-1||dfs(brea[i])){
                areb[node]=i;
                brea[i]=node;
                return true;
            }
        }
    }
    return false;
}
void prework(){
    int i,j;
    memset(used,false,sizeof(used));
    for (i=1;i<=n;i++){
        for (j=1;j<=m;j++){
            if (!used[j] && mymap[i][j]){
                used[j]=true;
                areb[i]=j;
                brea[j]=i;
                cnt++;
                break;
            }
        }
    }
}
void showre(){
    printf("%d\n",cnt);
    /*
    int i;
    for (i=1;i<=n;i++){
        if (areb[i]!=-1){
            printf("%d %d\n",i,areb[i]);
        }
    }
    */
}
void init(){
    memset(mymap,false,sizeof(mymap));
    int i,j;
    for (i=1;i<=n;i++){
        int len,node;
        scanf("%d",&len);
        for (j=0;j<len;j++){
            scanf("%d",&node);
            mymap[i][node]=true;
        }
    }
    memset(areb,-1,sizeof(areb));
    memset(brea,-1,sizeof(brea));
    cnt=0;
}
